﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace game
{
    public class Rocket : Projectile
    {
        protected const float aimEpsilon = MathHelper.Pi * 0.02f;

        protected const float turnSpeed = 0.003f;
        protected const float maxTurning = 0.6f;
        protected const float turnEpsilon = 0.1f;
        protected float turning = 0.0f;

        protected bool turnOrdered = false;

        protected float maxMoveSpeed;
        protected float acc = 0.13f;

        protected float dirToTarget = 0.0f;

        protected GameObject target = null;

        protected const int idleLifeTime = 100;
        protected int lifeTime = 0;

        private static ModelUnit modelInst = null;
        public static Rocket Create(Scene scene, Ship shooter, int layerIndex, Vector3 position, Vector3 rotation)
        {
            if (modelInst == null)
            {
                modelInst = new ModelUnit(ShooterGame.Instance.Content.Load<Model>("Models\\rocket"),
                    Matrix.CreateScale(2,3,2) * Matrix.CreateRotationX(MathHelper.PiOver2));
            }
            return new Rocket(scene, shooter, modelInst, layerIndex, position, rotation);
        }

        public Rocket(Scene scene, Ship shooter, ModelUnit model, int layerIndex, Vector3 position, Vector3 rotation)
            : base(scene, shooter, model, layerIndex, position, rotation)
        {
            this.maxMoveSpeed = 80.0f;
            this.moveSpeed = maxMoveSpeed * 0.6f;
            this.Health = 2.0f;
            this.MaxHealth = this.Health;
            this.damage = 20.0f;
            this.lifeTimeMs = 5000;

            regMove.LeanStablePointEpsilon = turnEpsilon;
            regMove.LeanSpeed = turnSpeed;
            regMove.MaxLean = maxTurning;

            pSystemOffset = 600.0f;
            
            target = shooter.Target;

            bSphere = new BoundingSphere(Vector3.Zero, 150);
        }

        public override void Update(GameTime gameTime)
        {
            lifeTime += gameTime.ElapsedGameTime.Milliseconds;

            if (target != null && lifeTime > idleLifeTime)
            {
                dirToTarget = (float)Math.Atan2(target.Position.X - position.X, target.Position.Z - position.Z);
                dirToTarget -= MathHelper.Pi;
                if (dirToTarget <= -MathHelper.Pi)
                    dirToTarget += MathHelper.TwoPi;
                if (rotation.Y - dirToTarget > aimEpsilon)
                {
                    if (rotation.Y - MathHelper.Pi > dirToTarget)
                    {
                        TurnLeft();
                    }
                    else
                    {
                        TurnRight();
                    }
                }
                else if (rotation.Y - dirToTarget < -aimEpsilon)
                {
                    if (rotation.Y + MathHelper.Pi < dirToTarget)
                    {
                        TurnRight();
                    }
                    else
                    {
                        TurnLeft();
                    }
                }
                else
                {
                    Align();
                }


                if (!target.IsAlive || target.LayerIndex != LayerIndex)
                {
                    target = null;
                }
            }
            else
            {
                Align();
            }

            rotation.Y = regMove.Rotate(rotation.Y, turning * 0.003f);

            if (lifeTime > idleLifeTime && moveSpeed != maxMoveSpeed)
            {
                moveSpeed += gameTime.ElapsedGameTime.Milliseconds * acc;
                if (moveSpeed > maxMoveSpeed)
                    moveSpeed = maxMoveSpeed;
            }
                
            
            base.Update(gameTime);
        }

        

        protected override void InitParticleSystem(Scene scene)
        {
            pSystem = new RocketTracePSystem(scene, position - moveDir * pSystemOffset);
            pSystem.Initialize();
        }

        protected void TurnLeft()
        {
            turning = regMove.Lean(turning, RegularMovement.LeanState.LEFT);
            turnOrdered = true;
        }

        protected void TurnRight()
        {
            turning = regMove.Lean(turning, RegularMovement.LeanState.RIGHT);
            turnOrdered = true;
        }

        protected void Align()
        {
            if (turning != 0.0f)
            {
                turning = regMove.Lean(turning, RegularMovement.LeanState.IDLE);
            }
        }
    }
}
